//
//  GEDCOM.m
//  GEDCOMEdit Data Model
//
//  Created by Colin Begg on 11/02/2012.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "GEDCOM.h"
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>

@implementation GEDCOMEntity

@synthesize level=_level;
@synthesize optionalXrefId = _optionalXrefId;
@synthesize tag = _tag;
@synthesize optionalLineValue = _optionalLineValue;

// Preferred initialiser
- (id)initWithString: (NSString *)GEDCOMLine
{
    // Line from GEDCOMFile
    NSString *trimmedLine = [GEDCOMLine stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
    if (trimmedLine == @"" )
    {
        // Empty line
        return nil;
    }

    if ([trimmedLine rangeOfString:@" "].length == 0)
    {
        // No level found, bug out
        NSLog(@"No level in GEDCOM line");
        return nil;        
    }
    return self;
}

- (BOOL) writeToFile: (NSString *)path
{
    // Append GEDCOM to file
    return NO;
}
@end


// GEDCOMFile Private Interface

@interface GEDCOMFile()

// Private properties
@property (nonatomic,strong) NSArray *lines;
@property (nonatomic) NSUInteger lineCount;

// Private methods
- (NSArray *) parseFileStringIntoLines: (NSString *)stringToParse;
- (int) parseLineIntoGEDCOMEntities: (NSString *)stringToParse;
@end

// GEDCOMFile Implementation
//
@implementation GEDCOMFile

// Properties
@synthesize fileHandle = _fileHandle;
@synthesize GEDCOMEntities = _GEDCOMEntities;
@synthesize entityCount = _entityCount;
@synthesize lineCount = _lineCount;
@synthesize lines=_lines;

// Getter for GEDCOMEntities
- (NSMutableArray *)GEDCOMEntities
{
    // Lazy instantiation of the array
    if (!_GEDCOMEntities)
    {
        _GEDCOMEntities = [[NSMutableArray alloc] init];
    }
    return _GEDCOMEntities;
}

// Getter for entityCount
- (NSNumber *) entityCount
{
    if (!_entityCount)
    {
        _entityCount = [[NSNumber alloc] init];
        _entityCount = [NSNumber numberWithInt:-1]; // initialise to rogue value
    }
    return _entityCount;
}

// Getter for lines
- (NSArray *)lines
{
    // Lazy instantiate array
    if (!_lines) _lines = [[NSArray alloc] init];
    return _lines;
}

// Private Instance Methods
- (NSArray *) parseFileStringIntoLines: (NSString *)stringToParse
{
    NSMutableArray *linesAndBlanks = [[stringToParse componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] mutableCopy];
    // iterate over array, removing blank lines
    NSUInteger i, count = [linesAndBlanks count];
    
    for (i = 0; i < count; i++)
    {
        // check for empty string
        if ([[linesAndBlanks objectAtIndex:i] length] == 0)
        {
            // remove the blank line
            [linesAndBlanks removeObjectAtIndex:i];
            i--;    // move back to previous line
        }
    }
    return [linesAndBlanks copy];
}

// Constructor from file
- (id) initWithContentsOfFileAtURL:(NSURL *)url
{
    NSError *error;         // Error return
    // Open file specified in path and read into string
    NSString *stringFromFileAtPath = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    if (stringFromFileAtPath == nil)
    {
        // Error reading from file or no space
        NSLog(@"Error reading from GEDCOM file %@\n%@", url, [error localizedFailureReason]);
        return nil; // Unsuccessful
    }
    
    // Parse whole string into lines
    self.lines = [self parseFileStringIntoLines: stringFromFileAtPath];
    
    // Declare the most recently decoded level
    int previousLevel = -1; // rogue value
    
    self.lineCount = self.lines.count;
    NSLog(@"Line count = %lu\n", self.lineCount);
    // Parse each line into GEDCOMEntities, ignore blank lines
    for (int index=0; index < self.lineCount; index++)
    {
        // initWithString initialiser must return nil if the line does not 
        // represent a valid GEDCOM entity
        GEDCOMEntity *newEntity = 
        [[GEDCOMEntity alloc] initWithString:[self.lines objectAtIndex:index]];
        if (newEntity != nil)
        {
            previousLevel = [newEntity level];
            // Add it to the GEDCOMEntities array
            [self.GEDCOMEntities addObject:newEntity];
        }
             
    }

    
    return self;
}



@end